import os
import shutil
import time
from tkinter import *
from tkinter import filedialog, messagebox
from concurrent.futures import ThreadPoolExecutor
import threading

class SyncApp:
    def __init__(self, root):
        self.root = root
        self.root.title("文件同步工具")
        self.root.geometry("500x400")
        
        self.task_list = []
        
        # 当前任务路径变量
        self.source_folder = ""
        self.target_folder = ""

        # 任务列表框
        self.task_label = Label(self.root, text="任务列表:")
        self.task_label.pack(pady=10)

        self.task_listbox = Listbox(self.root, height=10, width=50)
        self.task_listbox.pack(pady=10)

        # 添加任务按钮
        self.add_task_button = Button(self.root, text="添加同步任务", command=self.add_task)
        self.add_task_button.pack(pady=10)

        # 执行同步按钮
        self.sync_button = Button(self.root, text="执行同步", command=self.execute_sync)
        self.sync_button.pack(pady=10)

        # 任务状态输出框
        self.status_label = Label(self.root, text="同步状态：")
        self.status_label.pack(pady=10)
        
        self.status_text = Text(self.root, height=10, width=50)
        self.status_text.pack(pady=10)

        # 初始化线程池
        self.executor = ThreadPoolExecutor(max_workers=4)  # 最大线程数可以调整

    def add_task(self):
        # 选择源文件夹
        source_folder = filedialog.askdirectory(title="选择源文件夹")
        if not source_folder:
            return
        
        # 选择目标文件夹
        target_folder = filedialog.askdirectory(title="选择目标文件夹")
        if not target_folder:
            return
        
        task = {
            'source': source_folder,
            'target': target_folder
        }

        # 保存任务到任务列表
        self.task_list.append(task)
        self.task_listbox.insert(END, f"源: {source_folder} -> 目标: {target_folder}")
        
        # 清空源和目标路径
        self.source_folder = ""
        self.target_folder = ""

    def execute_sync(self):
        # 获取当前选择的任务
        selected_task_index = self.task_listbox.curselection()
        if not selected_task_index:
            messagebox.showerror("错误", "请选择一个同步任务!")
            return
        
        task = self.task_list[selected_task_index[0]]
        source_folder = task['source']
        target_folder = task['target']

        self.status_text.delete(1.0, END)
        self.status_text.insert(END, f"正在同步源: {source_folder} -> 目标: {target_folder}\n")

        # 使用线程池执行同步操作
        self.executor.submit(self.sync_files, source_folder, target_folder)

    def sync_files(self, source_folder, target_folder):
        # 遍历源文件夹中的所有文件
        for root, dirs, files in os.walk(source_folder):
            for file in files:
                source_file = os.path.join(root, file)
                relative_path = os.path.relpath(source_file, source_folder)
                target_file = os.path.join(target_folder, relative_path)
                
                target_file_dir = os.path.dirname(target_file)
                if not os.path.exists(target_file_dir):
                    os.makedirs(target_file_dir)
                
                # 比较源文件和目标文件的修改时间
                if not os.path.exists(target_file) or os.path.getmtime(source_file) > os.path.getmtime(target_file):
                    try:
                        shutil.copy2(source_file, target_file)
                        self.update_status(f"已同步: {file}")
                    except Exception as e:
                        self.update_status(f"同步失败: {file}, 错误: {e}")
                else:
                    self.update_status(f"跳过未修改文件: {file}")

        # 删除目标文件夹中源文件不存在的文件
        self.delete_removed_files(source_folder, target_folder)
        
        self.update_status("同步完成！")

        # 弹出消息框提示同步完成
        messagebox.showinfo("同步完成", "文件同步已完成！")

    def delete_removed_files(self, source_folder, target_folder):
        for root, dirs, files in os.walk(target_folder):
            for file in files:
                target_file = os.path.join(root, file)
                relative_path = os.path.relpath(target_file, target_folder)
                source_file = os.path.join(source_folder, relative_path)
                
                if not os.path.exists(source_file):
                    try:
                        os.remove(target_file)
                        self.update_status(f"已删除: {file}")
                    except Exception as e:
                        self.update_status(f"删除失败: {file}, 错误: {e}")

    def update_status(self, message):
        # 通过线程安全的方式更新UI
        self.status_text.insert(END, message + "\n")
        self.status_text.yview(END)
        self.root.update_idletasks()

if __name__ == "__main__":
    root = Tk()
    app = SyncApp(root)
    root.mainloop()
